
// 安装兼容 ts md5的ArrayBuffer加密类
//  npm install spark-md5
//  npm install axios
import { ElNotification } from 'element-plus'
import SparkMD5 from 'spark-md5';
import axios from 'axios';
// 配置上传地址
const VITE_APP_BASE_FILE = import.meta.env.VITE_APP_BASE_FILE;
const VITE_APP_BASE_UPLOAD_FILE = import.meta.env.VITE_APP_BASE_UPLOAD_FILE;

const request = axios.create({
    baseURL: VITE_APP_BASE_UPLOAD_FILE,
    timeout: 15000,
    withCredentials: false,
    transformRequest: []
  });
  request.interceptors.request.use(
    config => {
        if (config.method == "post"){
            config.headers["Content-Type"] = "multipart/form-data";
        } else {
            config.headers["Content-Type"] = "application/json; charset=UTF-8";
        }
        config.headers["Cache-Control"] = "no-cache";
        config.headers["clientId"] = "10002";
        config.headers["app-id"] = "10002";
        config.headers["app-key"] = "v4UKxIpIYXlpbIYn7GxEWRdUNLqwbeWW";
        return config;
    },
    error => {
        Promise.reject(error);
    }
)
// 删除文件
export const getFileDelete=(md5:any)=>{
    request({
        method: 'get',
        url: "/clear/"+md5,
    }).then((response:any)=>{
        console.info(response);
    }).catch((error:any)=>{
        console.info(error);
    })
}

/*
*你可能觉得自己看懂下面的代码了
*然而你并没有，相信我。
*糊弄过去算了，不然你会好多个晚上睡不着觉
*嘴里骂着这段注释，觉得自己很聪明，
*真能“优化”下面的代码。
*现在关上文件，去玩点别的吧。
*/
export const  loadFile=(option:any)=>{
    // console.info(option);
    // console.info('option',JSON.stringify(option));
    const spark = new SparkMD5.ArrayBuffer();// md5的ArrayBuffer加密类
    const fileReader = new FileReader();// 文件读取类
    const chunkSize = 1024 * 1024 * 5; // 单个分片大小  设置单片大小
    let md5 : string;// 文件的唯一标识
    const optionFile = option.file; // 需要分片的文件
    const optionData = option.data; // 配置需要上传的参数
    let fileChunkedList: Array<any> = []; // 文件分片完成之后的数组
    const percentage: Array<any> = []; // 文件上传进度的数组，单项就是一个分片的进度
    // 总片数
    let chunkCount = 1;
    if (option.file.size > chunkSize) {
        chunkCount = Math.ceil(option.file.size / chunkSize);
    }
    for (let i = 0; i < optionFile.size; i = i + chunkSize) {
        const tmp = optionFile.slice(i, Math.min((i + chunkSize), optionFile.size))
        if (i === 0) {
            fileReader.readAsArrayBuffer(tmp)
        }
        fileChunkedList.push(tmp)
    }
    let fileExt ='';
    fileExt = getFileExt(optionFile.type);
    console.info('fileExt',fileExt);
    if (!fileExt) {
        return option.onError('不允许上传的文件类型');
    }
    const updataPercentage = (e:any) => {
        console.info('e',e);
        let loaded = 0
        percentage.forEach(item => {
            loaded += item
        })
        e.percent = loaded / optionFile.size * 100
        option.onProgress(e)
    }
    fileReader.onload = async(e:any) => {
        spark.append(e.target.result);
        md5 = spark.end();
        // md5 = spark.end() + new Date().getTime();
        fileChunkedList = fileChunkedList.map((item:any, index:number) => {
            const formData = new FormData();
            if (optionData) {
                Object.keys(optionData).forEach(key => {
                    formData.append(key, optionData[key])
                })
                // formData.append(option.filename, item, option.file.name)// 文件
                formData.append("md5", md5);
                formData.append("uniqueFileName", md5);
                formData.append("chunkSize", chunkSize.toString());
                formData.append("chunkIndex",  index.toString());
                formData.append("file", item);
            }
            return { formData: formData, index: index }
        })
        fileCheck();
    }
    function onEncode(md5:any,result:any) {
        let timer : any = null;
            request({
                url:'/query/'+md5,
                method:"get",
            }).then((res:any)=>{
                const response = res.data;
                if(response.data.result=='ok'){
                    ElNotification({
                      title: '提示',
                      message: '上传成功！',
                      type: 'success',
                    });
                    clearInterval(timer);
                    const success = getBody(result.data)
                    option.onSuccess(success)
                    return;
                  }else if(response.data.result=='started'||response.data.result=='wait'||response.data.result=='merge'){
                    if(response.data.result=='started'){
                      ElNotification({
                        title: '提示',
                        message: '转码中，继续等待！',
                        type: 'warning',
                      });
                    }else if(response.data.result=='wait'){
                      ElNotification({
                        title: '提示',
                        message: '等待转码中，继续等待！',
                        type: 'warning',
                      });
                    }else if(response.data.result=='merge'){
                      ElNotification({
                        title: '提示',
                        message: '合并中，请等待！',
                        type: 'warning',
                      });
                    }
                    timer = setTimeout(()=>{
                        onEncode(md5,result);
                    },5000)
                  }else if(response.data.result=='error'||response.data.result=='skip'){
                    console.info("转码失败，删除！")
                    clearInterval(timer);
                    request({
                        url:'/clear/'+md5,
                        method:"get",
                    }).then((ress:any)=>{
                        ElNotification({
                            title: '错误',
                            message: '转码失败，已删除删除，请重新上传！',
                        });
                        console.info("删除成功！",ress)
                    }).catch((error:any)=>{
                        console.info("删除失败！",error)
                    })
                  }
            })
    }
    function fileCheck(){
        request({
            url:"/uploads",
            method:"get",
            params:{
                status:'md5Check',
                md5:md5,
                name:optionFile.name,
                ext:fileExt,
            }
        }).then((response:any) => {
            const result= response.data;
            if(result.code==0){
                if(result.data.ifExist==true){
                    if(result.data.fileType=='img'){
                        ElNotification({
                            title: '提示',
                            message: '上传完成！',
                            type: 'success',
                        })
                        const success = getBody(result.data)
                        option.onSuccess(success)
                        return;
                    }else if(result.data.fileType=='video'||result.data.fileType=='file'||result.data.fileType=='audio'){
                        onEncode(md5,result);
                    }
                }else{
                    sendRequest(fileChunkedList);
                }
            }else{
                option.onError(result)
            }
        }).catch((error:any)=>{
            option.onError(error)
        })
    }
    function sendRequest(chunks:any) {
        const len = chunks.length
        let counter = 0;
        const start = async() => {
            const item = chunks.shift();
            if (item) {
                request({
                    url:"/uploads",
                    method:"get",
                    params:{
                        status:"chunkCheck",
                        name:md5,
                        chunkIndex:counter,
                    }
                }).then((response:any) => {
                    const result = response.data;
                        if(result.data.ifExist==true){
                            counter++;
                            if (counter == len - 1) {
                                return toMerge();
                            }
                        }else{
                            request({
                                method:"post",
                                url:"/uploads",
                                data:item.formData,
                                onUploadProgress: (progressEvent:any) => {
                                    console.info('progressEvent',progressEvent);
                                    if (progressEvent.total > 0) {
                                        progressEvent.percent =progressEvent.loaded / progressEvent.total * 100
                                    }
                                    percentage[item.index] = progressEvent.loaded;
                                    updataPercentage(progressEvent)
                                }
                            }).then((response:any) => {
                                if (counter === len - 1) {
                                    ElNotification({
                                        title: '提示',
                                        message: '最后一个分片上传完成，等待合并！',
                                        type: 'success',
                                    })
                                    return toMerge();
                                } else {
                                    counter++;
                                    start();
                                    ElNotification({
                                        title: '提示',
                                        message: '分片'+counter+'上传完成！',
                                        type: 'success',
                                    })
                                }
                            }).catch((error:any)=>{
                                option.onError(error);
                            })
                        }
                }).catch((error:any)=>{
                    option.onError(error);
                })
            }
        }
        start();
    }
    function toMerge(){
        const data = {
            status: "chunksMerge",
            filesize: optionFile.size,
            md5:md5,
            ext:fileExt,
            fileoldname: optionFile.name,
            name: md5,
            chunks:chunkCount,
            category:'用户>头像',
            channel: 10002,
            userId:0,
            is_watermark:0,
            is_mp3:1,
            vts:2,
            fixed_screenshot:0,
        };
        request({
            method: 'get',
            url:"/uploads",
            params: data
        }).then((response:any)=>{
            const result= response.data;
            if(result.code===0){
                ElNotification({
                    title: '提示',
                    message: '分片合并完成！',
                    type: 'success',
                })
                fileCheck();
            }else{
                option.onError(result)
            }
        }).catch((error:any)=>{
            option.onError(error)
        })
    }
}
function getBody(event:any){
    if(event.wh){
        const sizes:any = event.wh.split('x');
        return {
            md5:event.md5,
            name:event.name,
            fileType: event.fileType,
            sourceFile:`${event.md5}|${event.size}|${event.wh}|${event.ext}`,
            source:`${VITE_APP_BASE_FILE}/${event.md5}/w/${sizes[0]}/h/${sizes[1]}/d/0.${event.ext}`,
            poster:`${VITE_APP_BASE_FILE}/${event.md5}/w/${sizes[0]}/h/${sizes[1]}/d/0.png`,
            duration:event.duration
        };
    }else{
        return {
            md5:event.md5,
            name:event.name,
            fileType: event.fileType,
            sourceFile:`${event.md5}|${event.size}|${event.wh}|${event.ext}`,
            source:`${VITE_APP_BASE_FILE}/${event.md5}/v.${event.ext}`,
            duration:event.duration
        }
    }
}
function getFileExt(type:any) {
    let ext = '';
    switch (type) {
      case "image/gif":
        ext = "gif";
        break;
      case "image/jpeg":
        ext = "jpg";
        break;
      case "image/png":
        ext = "png";
        break;
      case "application/vnd.ms-powerpoint":
        ext = "ppt";
        break;
      case "application/vnd.ms-excel":
        ext = "xls";
        break;
      case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
        ext = "pptx";
        break;
      case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
        ext = "xlsx";
        break;
      case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
        ext = "docx";
        break;
      case "application/msword":
        ext = "doc";
        break;
      case "application/pdf":
        ext = "pdf";
        break;
      case "application/x-rar-compressed":
        ext = "rar";
        break;
      case "application/zip":
        ext = "zip";
        break;
      case "application/x-zip-compressed":
        ext = "zip";
        break;
      case "audio/mpeg":
        ext = "mp3";
        break;
      case "audio/x-m4a":
        ext = "m4a";
        break;
      case "video/mp4":
        ext = "mp4";
        break;
      case "video/quicktime":
        ext = "mov";
        break;
      case "video/x-flv":
        ext = "flv";
        break;
      case "video/x-msvideo":
        ext = "avi";
        break;
      case "video/x-ms-wmv":
        ext = "vmv";
        break;
      default:
        ext = '';
    }
    return ext;
}
